#带块的方法调用
=begin
对象.方法名(参数列表) do |块变量|
    循环处理
end
对象.方法名(参数列表){|块变量|
    循环处理
}
=end

#循环，使用迭代器

#隐藏常规处理
=begin
File.open("") do |file| #作为块变量自动在最后执行了file.close
    file.each_line do |line|
        print line
    end
end
=end

#替换部分算法
=begin
Array#sort方法使用<=>运算符返回-1,0,1
=end
array=["John","Mary","LLP","Dancing"]
sort1=array.sort
p sort1 #=>["Dancing", "John", "LLP", "Mary"]
sort2=array.sort{|a,b| a<=>b}
p sort1.eql?(sort2) #=>true
sort3=array.sort{|a,b| a.length<=>b.length}
sort4=array.sort_by{|item| item.length}
p sort3.eql?(sort4) #=>true

#带块方法
def total(from,to)
    result=0
    from.upto(to){|num| # Integer#upto
        if block_given?
            result+=yield(num) #块处理的值
        else
            result+=num
        end
    }
    result
end
#传递块参数
p total(1,3),total(1,3){|num| num**2} #块处理num^2
#获取块的值
def block_args
    yield() # 0个块变量
    yield(1) # 1个块变量
    yield(1,2,3) # 3个块变量
end
block_args do |a| #通过a接收变量
    p [a] 
end
block_args do |a,b,c| #通过a,b,c接收变量
    p [a,b,c]
end
block_args do |*a| #通过*a接收变量
    p [a]
end

#控制块的执行
p total(1,3){|num| break if num==1} # break终止块内所有语句，回到调用块的地方
p total(1,3){|num| 
    if num%2!=0
        next 0
    end
    num
} #使用next后，yield会返回，默认nil，否则指定next 返回值

#将块封装为对象
#Proc#call
hello=Proc.new{|name| puts("Hello,#{name}")}
hello.call("张天泽")
def total_block(from,to,&block) #自动封装Proc对象
    result=0
    from.upto(to){|num|
        if block
            result+=block.call(num)
        else 
            result+=num
        end
    }
    return result
end
p total_block(1,3),total_block(1,3){|num| num*2}
def call_each(ary,&block)
    ary.each(&block)
end
call_each [1,2,3] do |item| #不知道为啥不能用{}
    p item
end

#局部变量与块变量
x,y=1,1
ary=[1,2,3]
ary.each do |x|
    y=x #块可以调用局部变量
end
p [x,y] 

x,y,z=0,0,0
ary.each do |x;y| # y作为块局部变量
    y=x
    z=x
    p [x,y,z]
end
p [x,y,z] #局部变量y没有改变